<template>
  <slot v-if="isShow" :disabled="isDisabled" :isShow="isShow"></slot>
</template>

<script setup>
import {watch, ref, onMounted} from 'vue'

defineOptions({name: "xhykPower"})

const props = defineProps({
  // 插槽，禁用权限。字符串时则有该权限就显示。一维数组[]时则只要有一个包含就显示。
  // 二维数组[string,[]]时则需要满足第一个string或满足第二个元素[]里面包含的全部才显示。
  disabled: {
    type: [String, Object],
    default: []
  },

  // 显示权限，如上。v-if
  show: {
    type: [String, Object],
    default: []
  },

  // 区分大小写
  lowerCase: {
    type: Boolean,
    default: false
  },

  // window保存的列表，如果全局取消权限，则window对应这个字段名称改为不一样，下面获取为undefined就会不进行权限判断
  name: {
    type: String,
    default: '$xhykPower'
  },
})

// 判断
function hasPermission(permissionList, permissionCheck, lowerCase = false) {
  // Helper function to convert to lowercase if caseInsensitive is true
  const normalize = (str) => lowerCase ? str.toLowerCase() : str;

  // Normalize the permissionList if caseInsensitive is true
  const normalizedPermissionList = permissionList.map(normalize);

  if (typeof permissionCheck === 'string') {
    return normalizedPermissionList.includes(normalize(permissionCheck));
  } else if (Array.isArray(permissionCheck)) {
    return permissionCheck.some(subCheck => {
      if (typeof subCheck === 'string') {
        return normalizedPermissionList.includes(normalize(subCheck));
      } else if (Array.isArray(subCheck)) {
        return subCheck.every(subSubCheck => normalizedPermissionList.includes(normalize(subSubCheck)));
      }
      return false;
    });
  }
  return false;
}

// 显示
const isShow = ref(false)

const setShowFn = () => {
  if (props.show == undefined || props.show.length <= 0) {
    isShow.value = true
    return;
  }
  const list = window[props.name] || undefined
  if (list == undefined) {
    isShow.value = true
    return;
  }
  isShow.value = hasPermission(list, props.show, props.lowerCase)
}

// 禁止
const isDisabled = ref(true)

const setDisabledFn = () => {
  if (props.disabled == undefined || props.disabled.length <= 0) {
    isDisabled.value = false
    return;
  }
  const list = window[props.name] || undefined
  if (list == undefined) {
    isDisabled.value = false
    return;
  }
  isDisabled.value = !hasPermission(list, props.disabled, props.lowerCase)
}

// 获取结果。true代表允许通过
const getPowerFn = (permissionCheck) => {
  const list = window[props.name] || undefined
  if (list == undefined) {
    return true
  }
  return hasPermission(list, permissionCheck, props.lowerCase)
}

watch([() => props.disabled, () => props.show, () => props.name], (newV, oldV) => {
  setShowFn()
  setDisabledFn()
}, {immediate: true, deep: true})

onMounted(() => {
  setShowFn()
  setDisabledFn()
})

defineExpose({
  getPower: getPowerFn
})
</script>

<style scoped lang='scss'>

</style>